﻿using Windows.UI.Xaml;
using Windows.UI.Xaml.Markup;

namespace Uhimania.Libraries.Windows.Interactivity
{
    #region TriggerBase
    /// <summary>
    /// 条件付きで <see cref="TriggerAction"/> を呼び出せるオブジェクトを表す。
    /// </summary>
    [ContentProperty(Name="Actions")]
    public abstract class TriggerBase : AttachedObjectBase
    {
        #region Actions

        /// <summary>
        /// <see cref="Actions"/> を識別する依存関係プロパティ。
        /// </summary>
        private static readonly DependencyProperty ActionsProperty =
            DependencyProperty.Register(
                "Actions",
                typeof(TriggerActionCollection),
                typeof(TriggerBase),
                new PropertyMetadata(new TriggerActionCollection())
            );

        /// <summary>
        /// このトリガーに関連付けられているアクションを取得する。
        /// </summary>
        public TriggerActionCollection Actions
        {
            get { return this.GetValue(ActionsProperty) as TriggerActionCollection; }
        }

        #endregion

        #region Attach
        /// <summary>
        /// 指定されたオブジェクトにアタッチする。
        /// </summary>
        /// <param name="associatedObject">アタッチするオブジェクト。</param>
        public new void Attach(DependencyObject associatedObject)
        {
            this.AssociatedObject = associatedObject;
            this.Actions.Attach(associatedObject);
            this.OnAttached();
        }
        #endregion

        #region Detach
        /// <summary>
        /// このインスタンスを関連オブジェクトからデタッチする。
        /// </summary>
        public new void Detach()
        {
            this.OnDetaching();
            this.AssociatedObject = null;
            this.Actions.Detach();
        }
        #endregion

        #region InvokeActions
        /// <summary>
        /// このトリガーに関連するすべてのアクションを呼び出す。
        /// </summary>
        /// <param name="parameter">アクションへのパラメータ。</param>
        protected void InvokeActions(object parameter)
        {
            foreach (var action in this.Actions)
                action.CallInvoke(parameter);
        }
        #endregion
    }
    #endregion

    #region TriggerBase<T>
    /// <summary>
    /// 条件付きで <see cref="TriggerAction"/> を呼び出せるオブジェクトを表す。
    /// </summary>
    /// <typeparam name="T"><see cref="TriggerBase" /> をアタッチできる型。</typeparam>
    public abstract class TriggerBase<T> : TriggerBase
        where T : DependencyObject
    {
        #region AssociatedObject
        /// <summary>
        /// この <see cref="TriggerBase" /> がアタッチされるオブジェクトを取得する。
        /// </summary>
        public new T AssociatedObject
        {
            get { return base.AssociatedObject as T; }
        }
        #endregion
    }
    #endregion
}
